"""MariaDB Connection Handler."""
from collections import abc
import contextlib
import os
import typing

import mysql.connector
import prometheus_client as prometheus

METRIC_TIME = prometheus.Histogram(
    'cki_mariadb_query_duration_seconds', 'Time spent handling a query',
    ['hostname', 'query'],
)


class MariaDBHandler:
    """MariaDB connection handler."""

    def __init__(self) -> None:
        """Initialize MariaDB connection."""
        self.connection_params = {
            'host': os.environ['MARIADB_HOST'],
            'port': int(os.environ['MARIADB_PORT']),
            'user': os.environ['MARIADB_USER'],
            'password': os.environ['MARIADB_PASSWORD'],
            'database': os.environ['MARIADB_DATABASE'],
            'collation': os.environ.get('MARIADB_COLLATION', 'utf8mb4_general_ci'),
            'autocommit': True,
        }

    @contextlib.contextmanager
    def cursor(self):
        """Get DB connection."""
        connection = mysql.connector.connect(**self.connection_params)
        try:
            yield connection.cursor()
        finally:
            connection.close()

    @staticmethod
    def tuple_placeholder(vals: abc.Sized) -> str:
        """Return a proper placeholder for a tuple."""
        return '(' + ('%s,' * len(vals))[:-1] + ')'

    def execute(self, query: str, *args: typing.Any) -> list[list[typing.Any]]:
        """Execute a given query."""
        with METRIC_TIME.labels(
                self.connection_params['host'], ' '.join(query.split())
        ).time(), self.cursor() as cursor:
            cursor.execute(query, *args)
            return typing.cast(list[list[typing.Any]], cursor.fetchall())
